package com.aquarium.sensor;

import java.util.HashMap;
import java.util.Observable;
import java.util.Timer;
import java.util.TimerTask;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.aquarium.alarm.AlarmManager;
import com.aquarium.bt.DataStruct;
import com.aquarium.bt.RecvDataDispatcher;
import com.aquarium.config.AlarmDefaultValue;
import com.aquarium.config.BTDataConfig;
import com.aquarium.history.HistoryManager;
import com.aquarium.ui.SensorValueDisplayActivity;

public class SensorManager extends Observable {

	public final static String PH_VALUE_KEY = "PH_VALUE_KEY";
	public final static String TEMPERATURE_VALUE_KEY = "TEMPERATURE_VALUE_KEY";
	public final static String OXYGEN_VALUE_KEY = "OXYGEN_VALUE_KEY";
	public final static String CONDUCTIVITY_VALUE_KEY = "CONDUCTIVITY_VALUE_KEY";
	public final static String WATER_LEVEL_VALUE_KEY = "WATER_LEVEL_VALUE_KEY";

	public final static int HANDLE_PH_VALUE = 0;
	public final static int HANDLE_TEMPERATURE_VALUE = 1;
	public final static int HANDLE_OXYGEN_VALUE = 2;
	public final static int HANDLE_CONDUCTIVITY_VALUE = 3;
	public final static int HANDLE_WATER_LEVEL_VALUE = 4;

	private static SensorManager mSensorManager;
	private RecvDataDispatcher mRecvDataDispatcher;

	private float mCurrentPhValue;
	private float mCurrentTemperatureValue;
	private float mCurrentOxygenValue;
	private float mCurrentConductivityValue;
	private float mCurrentWaterLevelValue;
	private HashMap<String, String> mSensorValueMap;

	// test code
	private Timer mNotifySensorValueTimer;

	private SensorManager() {
		mSensorValueMap = new HashMap<String, String>();
		mRecvDataDispatcher = RecvDataDispatcher.getInstance();
		mRecvDataDispatcher.setSensorValueHandler(mSensorValueHandler);
	}

	/**
	 * {@link RecvDataDispatcher} will use this handler to send sensor value
	 * data to {@link Handler#handleMessage(Message)}
	 */
	private Handler mSensorValueHandler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case HANDLE_PH_VALUE:
				if (msg.obj instanceof String) {
					mCurrentPhValue = Float.valueOf((String) msg.obj);
				}
				break;
			case HANDLE_TEMPERATURE_VALUE:
				if (msg.obj instanceof String) {
					mCurrentTemperatureValue = Float.valueOf((String) msg.obj);
				}
				break;
			case HANDLE_OXYGEN_VALUE:
				if (msg.obj instanceof String) {
					mCurrentOxygenValue = Float.valueOf((String) msg.obj);
				}
				break;
			case HANDLE_CONDUCTIVITY_VALUE:
				if (msg.obj instanceof String) {
					mCurrentConductivityValue = Float.valueOf((String) msg.obj);
				}
				break;
			case HANDLE_WATER_LEVEL_VALUE:
				if (msg.obj instanceof String) {
					mCurrentWaterLevelValue = Float.valueOf((String) msg.obj);
				}
				break;

			default:
				break;
			}
		};
	};

	public static SensorManager getInstance() {
		if (mSensorManager == null) {
			mSensorManager = new SensorManager();
		}
		return mSensorManager;
	}

	/**
	 * 获取ph值
	 * 
	 * @return ph值
	 */
	public float getPhValue() {
		// TODO
		return 0;
	}

	/**
	 * 获取水温值
	 * 
	 * @return 水温值
	 */
	public float getTemperature() {
		// TODO
		return 0;
	}

	/**
	 * 获取含氧量
	 * 
	 * @return 含氧量
	 */
	public float getOxygenLevel() {
		// TODO
		return 0;
	}

	/**
	 * 获取咸度（导电率）
	 * 
	 * @return 导电率
	 */
	public float getConductivity() {
		// TODO
		return 0;
	}

	/**
	 * 獲取水位
	 * 
	 * @return 水位
	 */
	public float getWaterLevel() {
		// TODO
		return 0;
	}

	/**
	 * Notify and send current sensor value to observers, such as
	 * {@link SensorValueDisplayActivity}, {@link AlarmManager} and
	 * {@link HistoryManager}
	 */
	public void notifySensorValueChanged() {
		mSensorValueMap.clear();
		mSensorValueMap.put(PH_VALUE_KEY, String.valueOf(mCurrentPhValue));
		mSensorValueMap.put(TEMPERATURE_VALUE_KEY,
				String.valueOf(mCurrentTemperatureValue));
		mSensorValueMap.put(OXYGEN_VALUE_KEY,
				String.valueOf(mCurrentOxygenValue));
		mSensorValueMap.put(CONDUCTIVITY_VALUE_KEY,
				String.valueOf(mCurrentConductivityValue));
		mSensorValueMap.put(WATER_LEVEL_VALUE_KEY,
				String.valueOf(mCurrentWaterLevelValue));

		setChanged();
		notifyObservers(mSensorValueMap);
	}

	/**
	 * flush and get latest sensor value form remote BT device
	 * 
	 * @param data
	 *            The command(request sensor value command) to send
	 */
	public void flushSensorValue(DataStruct data) {
		// TODO
	}

	public HashMap<String, String> getSensorValueMap() {
		return mSensorValueMap;
	}

	/**
	 * test code
	 */
	public void notifySensorValueTest() {
		if (mNotifySensorValueTimer != null) {
			mNotifySensorValueTimer.cancel();
		}
		mNotifySensorValueTimer = new Timer();
		mNotifySensorValueTimer.schedule(new TimerTask() {

			@Override
			public void run() {
				notifySensorValueChanged();
			}
		}, 800, 5000);

	}

	/**
	 * test code
	 */
	public void stopNotifySensorValueTest() {
		if (mNotifySensorValueTimer == null) {
			return;
		}
		mNotifySensorValueTimer.cancel();
	}

}
